package jyrc;



import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;

import org.jdom.*;
import org.jdom.output.*;





/**
 * This servlet aim to make communicate a JyRC client with a JyRC server.
 * <p>
 * Because a user could launch several clients with the same browser, a session could have to manage several clients with
 * several servers. That's why each client have an session-unique id; the session is used like and HashMap&lt;JyRCServer&gt;.
 * <p>
 * There're 3 actions to handle: the connection of a new client (0); the checkout (1); the posting (2);<br/>
 * 0. When a client send a GET request and he has no server associated, a new one is created and stored in a session.
 * 1. When a client send a GET request and has his own JyRC server, the checkout is done.
 * 2. All connected clients (meaning it has got an associated server) which send a POST request posts a message to his server.
 */



public class JyRCServlet extends HttpServlet {

	/**
	 * We do NOT want bots like GoogleBot to index this servlet.
	 */
	public void doHead(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		response.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED);
	}



	protected static final String ID_KEY = "jyrcid", POST_VALUE_KEY = "postvalue";
	private XMLOutputter xmlOutputter = null;

	public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		JyRCServer jyrcServer;
		HttpSession session = request.getSession();
		if(session.isNew())
			session.setMaxInactiveInterval(90);
		String id = request.getParameter(ID_KEY);
		if(id == null || "".equals(id) || "<*>".equals(id) || "undefined".equals(id)) {
			jyrcServer = new DummyJyRCServer(); // *** this is only for testing
			id = Integer.toHexString(jyrcServer.hashCode());
			while(session.getAttribute(id) != null)
				id += Double.toHexString(System.currentTimeMillis()*Math.random());
			session.setAttribute(id,jyrcServer);
			response.getWriter().println(id+"|");
		} else {
			jyrcServer = (JyRCServer) session.getAttribute(id);
			if(jyrcServer == null) {
				response.sendError(HttpServletResponse.SC_FORBIDDEN);
				return;
			}
			try {	Document xml = new Document(new Element("checked-out"));
				for(JyRCPost post : jyrcServer.checkout())
					xml.getRootElement().addContent(post.toXmlElement());
				if(xmlOutputter == null)
					xmlOutputter = new XMLOutputter();
				xmlOutputter.output(xml, response.getOutputStream());
			} catch(JyRCServerException e) {
				response.sendError(HttpServletResponse.SC_EXPECTATION_FAILED, e.getMessage());
			}
		}
	}

	public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		JyRCServer jyrcServer;
		HttpSession session = request.getSession(false); // do NOT auto-create
		String id = request.getParameter(ID_KEY);
		if(session == null || id == null) {
			response.sendError(HttpServletResponse.SC_FORBIDDEN);
			return;
		}
		jyrcServer = (JyRCServer) session.getAttribute(id);
		if(jyrcServer == null) {
			response.sendError(HttpServletResponse.SC_FORBIDDEN);
			return;
		}
		try { jyrcServer.post(request.getParameter(POST_VALUE_KEY));
		} catch(JyRCServerException e) {
			response.sendError(HttpServletResponse.SC_EXPECTATION_FAILED, e.getMessage());
		}
	}
}
